import os
import requests
from requests.auth import HTTPBasicAuth
import pandas as pd


def band_one_sld(service_url, layer_name, style_name):
    url = service_url + "/rest/layers/" + layer_name
    auth = ("admin", "geoserver")
    headers = {"Content-type": "text/xml"}
    data = "<layer><defaultStyle><name>" + style_name + "</name></defaultStyle></layer>"
    response = requests.request(
        "PUT",
        url,
        auth=auth,
        headers=headers,
        data=data.encode('utf-8')
    )

    curlStr = '''curl -X PUT \
     -u "admin:geoserver" \
     -H "Content-type: text/xml" \
     -d "<layer><defaultStyle><name>${style_name}</name></defaultStyle></layer>" \
     "${service_url}/rest/layers/${layer_name}"'''.replace("${style_name}",style_name).replace("${layer_name}", layer_name).replace("${service_url}", service_url)
    print(f"{curlStr} " + "&")
    if (response.status_code == 200):
        print(f"{layer_name}图层绑定 {style_name} 样式成功")
    else:
        print(f"{layer_name} 图层绑定 {style_name} 样式失败", layer_name, style_name)


def band_sld(service_url):
    excel_file = '重庆.xlsx'
    df = pd.read_excel(excel_file)
    # 遍历每一行
    for index, row in df.iterrows():
        p_type = row['p_type']
        point_names = row['point_layer_names']
        line_names = row['line_layer_names']

        if not pd.isna(line_names):
            line_names_list = line_names.split(',')
            for line_names in line_names_list:
                band_one_sld(service_url, line_names, p_type + "_line")

        if not pd.isna(point_names):
            point_names_list = point_names.split(',')
            for point_names in point_names_list:
                band_one_sld(service_url, point_names, p_type + "_point")


def read_sld(sld_path):
    sld_content = ""
    with open("out/" + sld_path, 'r', encoding='utf-8') as lineXml:
        sld_content = lineXml.read()
    return sld_content


def push_sld(service_url, style_name):
    style_base_name = os.path.splitext(style_name)[0]

    delete_endpoint = f"{service_url}/rest/styles/" + style_base_name
    update_endpoint = f"{service_url}/rest/styles/" + style_base_name
    post_endpoint = f"{service_url}/rest/styles?name=" + style_base_name

    auth = HTTPBasicAuth("admin", "geoserver")
    headers = {'Content-type': 'application/vnd.ogc.sld+xml;charset=utf-8'}
    check_response = requests.get(
        delete_endpoint,
        auth=auth,
        headers={'Accept': 'application/json'}
    )
    sld_content = read_sld(style_name)

    if check_response.status_code == 200:
        print(f"{style_base_name}样式已经存在，将进行更新", style_base_name)
        # 样式存在，使用 PUT 更新
        method = 'PUT'
        delete_response = requests.request(
            method,
            update_endpoint,
            auth=auth,
            headers=headers,
            data=sld_content.encode('utf-8')
        )
        delete_code = delete_response.status_code
        if (delete_code == 200):
            print(f"{style_base_name}更新成功")
        else:
            print(
                f"{style_base_name}更新失败,url:{update_endpoint}, status_code:{delete_code},error:{delete_response.text}")
    else:
        print(f"{style_base_name}样式已经不存在，将进行推送", style_base_name)
        # 样式不存在，使用 POST 创建
        method = 'POST'
        # 发送创建请求
        print(f"推送url: {delete_endpoint}")
        post_response = requests.request(
            method,
            post_endpoint,
            auth=auth,
            headers=headers,
            data=sld_content.encode('utf-8')
        )
        status_code = post_response.status_code
        if status_code in (200, 201):
            print(f"{style_base_name} 样式推送成功")
        else:
            print(
                f"{style_base_name} 样式推送失败,status_code:{status_code} url:{delete_endpoint},error: {post_response.text}")


if __name__ == '__main__':
    service_url = "http://localhost:8080/geoserver"
    # 推送样式（如果样式已经推送过，可注释下面的4行代码）
    for root, dirs, files in os.walk("out"):
        for file in files:
            if file.lower().endswith('.sld'):
                push_sld(service_url, file)

    # 绑定样式
    band_sld(service_url)
